/**
 *   Copyright 2014 Royce Remulla
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package cjcast.common;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Input file reader.
 * 
 * <pre>
 * $Author: royce.com@gmail.com $ 
 * $Date: 2015-02-03 03:44:46 +0000 (Tue, 03 Feb 2015) $ 
 * $HeadURL: http://codejam-cast.googlecode.com/svn/trunk/src/main/java/cjcast/common/CjInputReader.java $
 * </pre>
 * 
 * @param <T> case type.
 * 
 * @author Royce Remulla
 */
public class CjInputReader<T> implements Iterable<T>, Iterator<T> {


    /** File reader/writer. */
    private final transient ReadWriteTextFileJDK7 fileUtil = new ReadWriteTextFileJDK7();

    /** File line by line contents. */
    private final transient String[] fileLines;

    /** Iterator pointer. */
    private transient int pointer = 1; //NOPMD Bug, could not detect += operator.

    /** */
    private final transient int caseTotal;

    /** Base 1. */
    private transient int caseCurrentIndex;


    /** */
    private final transient int caseUnitSize;

    /** Converter instance. */
    private final transient CaseConverter<T> converter;

    /**
     * 
     * @param pInputfile Input file.
     * @param pCaseUnitSize size of problem case. Number of successive lines
     *            belonging to the same case.
     * @param pConverter instance to parse and convert to case problem object.
     * @throws IOException if an IO exception occurs during read line.
     */
    public CjInputReader(final File pInputfile, final int pCaseUnitSize,
            final CaseConverter<T> pConverter) throws IOException {

        final List<String> lineList = fileUtil.readLargeTextFile(pInputfile
            .getAbsolutePath());

        this.converter = pConverter;
        this.caseTotal = Integer.parseInt(lineList.get(0));
        this.caseUnitSize = pCaseUnitSize;
        this.fileLines = lineList.toArray(new String[lineList.size()]);
        this.caseCurrentIndex = 0;
    }

    /**
     * @return the caseTotal
     */
    public int getCaseTotal()
    {
        return this.caseTotal;
    }


    /** {@inheritDoc} */
    @Override
    public boolean hasNext()
    {
        return this.pointer < this.fileLines.length;
    }


    /**
     * @see java.util.Iterator#next()
     */
    @Override
    public T next()
    {
        T retval = null; //NOPMD: null default, conditionally redefine.
        if (hasNext()) {
            ++this.caseCurrentIndex;

            final List<String> paramList = new ArrayList<String>();

            for (int i = 0; i < getCaseSize(); i++) {
                final int currentIndex = this.pointer + i;
                paramList.add(this.fileLines[currentIndex]);
            }

            retval = this.converter.convert(paramList
                .toArray(new String[paramList.size()]));
        }

        this.pointer += getCaseSize();
        return retval;
    }

    public int getCaseSize()
    {
        return this.caseUnitSize;
    }


    /**
     * Unsupported.
     * 
     * {@inheritDoc}
     */
    @Override
    public void remove()
    {
        throw new UnsupportedOperationException("Not implemented. ");

    }

    /** {@inheritDoc} */
    @Override
    public Iterator<T> iterator()
    {
        return this;
    }

    public ReadWriteTextFileJDK7 getFileUtil()
    {
        return fileUtil;
    }

    public int getCaseCurrentIndex()
    {
        return caseCurrentIndex;
    }


}